package com.luyuan.gallery.util;

import com.luyuan.common.core.redis.RedisCache;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Set;

/**
 * Redis点赞工具类
 * 使用ZSet存储点赞信息，score为时间戳，value为用户ID
 * 使用String存储用户点赞记录，用于快速判断用户是否已点赞
 * 
 * @author luyuan
 * @date 2025-11-19
 */
@Component
public class RedisLikeUtils {

    private static RedisLikeUtils redisLikeUtils;

    @PostConstruct
    public void init() {
        redisLikeUtils = this;
        redisLikeUtils.redisCache = this.redisCache;
    }

    private RedisCache redisCache;

    /**
     * 点赞
     * 
     * @param bizId 业务ID
     * @param bizType 业务类型(1-展厅，2-作品，3-评论)
     * @param userId 用户ID
     * @return true-点赞成功，false-取消点赞成功
     */
    public static boolean like(Long bizId, Integer bizType, Long userId) {
        String key = buildLikeKey(bizId, bizType);
        Double score = redisLikeUtils.redisCache.redisTemplate.opsForZSet().score(key, userId.toString());
        
        // 如果已经点赞，则取消点赞
        if (score != null) {
            // 从有序集合中移除
            redisLikeUtils.redisCache.redisTemplate.opsForZSet().remove(key, userId.toString());
            // 移除用户点赞记录
            redisLikeUtils.redisCache.deleteObject(buildUserLikeKey(userId, bizId, bizType));
            return false;
        } else {
            // 添加点赞记录
            long timestamp = System.currentTimeMillis();
            redisLikeUtils.redisCache.redisTemplate.opsForZSet().add(key, userId.toString(), timestamp);
            // 记录用户点赞信息
            redisLikeUtils.redisCache.setCacheObject(buildUserLikeKey(userId, bizId, bizType), Double.valueOf(timestamp));
            return true;
        }
    }

    /**
     * 获取点赞数
     * 
     * @param bizId 业务ID
     * @param bizType 业务类型
     * @return 点赞数
     */
    public static long getLikeCount(Long bizId, Integer bizType) {
        String key = buildLikeKey(bizId, bizType);
        Long size = redisLikeUtils.redisCache.redisTemplate.opsForZSet().zCard(key);
        return size == null ? 0 : size;
    }

    /**
     * 获取用户点赞时间
     * 
     * @param bizId 业务ID
     * @param bizType 业务类型
     * @param userId 用户ID
     * @return 点赞时间戳，未点赞返回null
     */
    public static Double getUserLikeTime(Long bizId, Integer bizType, Long userId) {
        String key = buildLikeKey(bizId, bizType);
        return redisLikeUtils.redisCache.redisTemplate.opsForZSet().score(key, userId.toString());
    }

    /**
     * 判断用户是否点赞
     * 
     * @param bizId 业务ID
     * @param bizType 业务类型
     * @param userId 用户ID
     * @return true-已点赞，false-未点赞
     */
    public static boolean isLiked(Long bizId, Integer bizType, Long userId) {
        String key = buildLikeKey(bizId, bizType);
        Double score = redisLikeUtils.redisCache.redisTemplate.opsForZSet().score(key, userId.toString());
        return score != null;
    }

    /**
     * 获取点赞用户列表（按时间倒序）
     * 
     * @param bizId 业务ID
     * @param bizType 业务类型
     * @param start 起始位置
     * @param end 结束位置
     * @return 点赞用户ID集合
     */
    public static Set<ZSetOperations.TypedTuple<String>> getLikeUsers(Long bizId, Integer bizType, long start, long end) {
        String key = buildLikeKey(bizId, bizType);
        return redisLikeUtils.redisCache.redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
    }

    /**
     * 构建点赞key
     * 
     * @param bizId 业务ID
     * @param bizType 业务类型
     * @return key
     */
    private static String buildLikeKey(Long bizId, Integer bizType) {
        return "like:" + bizType + ":" + bizId;
    }

    /**
     * 构建用户点赞记录key
     * 
     * @param userId 用户ID
     * @param bizId 业务ID
     * @param bizType 业务类型
     * @return key
     */
    private static String buildUserLikeKey(Long userId, Long bizId, Integer bizType) {
        return "user:like:" + userId + ":" + bizType + ":" + bizId;
    }
}